package com.lh0811.forge.pserv.uacs.server.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.lh0811.forge.dependency.basic_code.BeanHelper;
import com.lh0811.forge.dependency.basic_code.IdWorker;
import com.lh0811.forge.dependency.basic_web.exception.CommonException;
import com.lh0811.forge.dependency.basic_web.response.ServerResponse;
import com.lh0811.forge.dependency.security.client.component.SecurityUtil;
import com.lh0811.forge.dependency.security.core.model.entity.SecurityAuthority;
import com.lh0811.forge.pserv.basic.api.api.BizNoBaseApi;
import com.lh0811.forge.pserv.uacs.api.constant.UacsContant;
import com.lh0811.forge.pserv.uacs.api.param.*;
import com.lh0811.forge.pserv.uacs.api.vo.UacsPlateResQueryVo;
import com.lh0811.forge.pserv.uacs.api.vo.UacsPlateRoleQueryVo;
import com.lh0811.forge.pserv.uacs.server.repository.dao.UacsPlateResDao;
import com.lh0811.forge.pserv.uacs.server.repository.dao.UacsPlateRoleDao;
import com.lh0811.forge.pserv.uacs.server.repository.dao.UacsPlateRoleResRefDao;
import com.lh0811.forge.pserv.uacs.server.repository.dao.UacsTenantPostRoleRefDao;
import com.lh0811.forge.pserv.uacs.server.repository.entity.UacsPlateRes;
import com.lh0811.forge.pserv.uacs.server.repository.entity.UacsPlateRole;
import com.lh0811.forge.pserv.uacs.server.repository.entity.UacsPlateRoleResRef;
import com.lh0811.forge.pserv.uacs.server.repository.entity.UacsTenantPostRoleRef;
import com.lh0811.forge.pserv.uacs.server.service.PlateRoleService;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PlateRoleServiceImpl implements PlateRoleService {

    @Resource
    private BizNoBaseApi bizNoBaseApi;

    @Resource
    private UacsPlateRoleDao uacsPlateRoleDao;

    @Resource
    private UacsTenantPostRoleRefDao uacsTenantPostRoleRefDao;

    @Resource
    private UacsPlateRoleResRefDao uacsPlateRoleResRefDao;

    @Resource
    private UacsPlateResDao uacsPlateResDao;


    // 新建角色信息
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void plateRoleCreate(UacsPlateRoleCreateParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsPlateRole uacsPlateRole = new UacsPlateRole();
        uacsPlateRole.setId(IdWorker.nextId()); // 主键
        uacsPlateRole.setRoleName(param.getRoleName()); // 角色名称
        uacsPlateRole.setRoleNo(bizNoBaseApi.getNextNumByBizType(UacsContant.BizNoType.角色编号.getBizType())); // 角色编号
        uacsPlateRole.setNotes(param.getNotes()); // 备注
        uacsPlateRole.setCreateTime(new Date()); // 创建时间
        uacsPlateRole.setCreateBy(Long.valueOf(securityAuthority.getUserId())); // 创建人
        uacsPlateRoleDao.save(uacsPlateRole);
    }


    // 删除角色信息
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void plateRoleDelete(Long roleId) throws Exception {
        UacsPlateRole role = uacsPlateRoleDao.getById(roleId);
        if (ObjectUtils.isEmpty(role)) {
            throw CommonException.create(ServerResponse.createByError("角色信息不存在"));
        }
        // 是否被岗位引用
        if (BooleanUtils.isTrue(uacsTenantPostRoleRefDao.lambdaQuery().eq(UacsTenantPostRoleRef::getRoleId, roleId).exists())) {
            throw CommonException.create(ServerResponse.createByError("角色已被岗位引用不可删除"));
        }
        // 移除与资源的关联关系
        List<UacsPlateRoleResRef> roleResRefList = uacsPlateRoleResRefDao.lambdaQuery().eq(UacsPlateRoleResRef::getRoleId, roleId).list();
        if (CollectionUtils.isNotEmpty(roleResRefList)) {
            uacsPlateRoleResRefDao.removeByIds(roleResRefList.stream().map(ele -> ele.getId()).collect(Collectors.toList()));
        }
        // 移除角色
        uacsPlateRoleDao.removeById(roleId);
    }


    // 更新角色信息
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void plateRoleUpdate(UacsPlateRoleUpdateParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsPlateRole role = uacsPlateRoleDao.getById(param.getId());
        if (ObjectUtils.isEmpty(role)) {
            throw CommonException.create(ServerResponse.createByError("角色信息不存在"));
        }
        UacsPlateRole updateInfo = BeanHelper.copyBean(param, UacsPlateRole.class);
        updateInfo.setUpdateTime(new Date());
        updateInfo.setUpdateBy(Long.valueOf(securityAuthority.getUserId()));
        uacsPlateRoleDao.updateById(updateInfo);
    }


    // 查询角色信息(分页)
    @Override
    public PageInfo<UacsPlateRoleQueryVo> plateRoleQueryPage(UacsPlateRoleQueryPageParam param) throws Exception {
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<UacsPlateRole> list = uacsPlateRoleDao.lambdaQuery()
                .like(StringUtils.isNotBlank(param.getRoleName()), UacsPlateRole::getRoleName, param.getRoleName())
                .like(StringUtils.isNotBlank(param.getRoleNo()), UacsPlateRole::getRoleNo, param.getRoleNo())
                .orderByDesc(UacsPlateRole::getCreateTime)
                .list();
        PageInfo pageInfo = new PageInfo<>(list);
        PageHelper.clearPage();
        pageInfo.setList(BeanHelper.copyList(list, UacsPlateRoleQueryVo.class));
        return pageInfo;
    }


    // 查询角色信息(不分页)
    @Override
    public List<UacsPlateRoleQueryVo> plateRoleQueryList(UacsPlateRoleQueryListParam param) throws Exception {
        List<UacsPlateRole> list = uacsPlateRoleDao.lambdaQuery()
                .like(StringUtils.isNotBlank(param.getRoleName()), UacsPlateRole::getRoleName, param.getRoleName())
                .like(StringUtils.isNotBlank(param.getRoleNo()), UacsPlateRole::getRoleNo, param.getRoleNo())
                .orderByDesc(UacsPlateRole::getCreateTime)
                .list();
        return BeanHelper.copyList(list, UacsPlateRoleQueryVo.class);
    }

    // 保存角色和资源关系
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void plateRoleResRefSave(UacsPlateRoleResRefSaveParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsPlateRole role = uacsPlateRoleDao.getById(param.getRoleId());
        if (ObjectUtils.isEmpty(role)) {
            throw CommonException.create(ServerResponse.createByError("角色信息不存在"));
        }

        // 移除关联信息
        List<UacsPlateRoleResRef> plateRoleResRefList = uacsPlateRoleResRefDao.lambdaQuery().eq(UacsPlateRoleResRef::getRoleId, param.getRoleId()).list();
        if (CollectionUtils.isNotEmpty(plateRoleResRefList)) {
            uacsPlateRoleResRefDao.removeByIds(plateRoleResRefList.stream().map(ele -> ele.getId()).collect(Collectors.toList()));
        }
        // 增加新的关联关系
        if (CollectionUtils.isNotEmpty(param.getResIdList())) {
            List<UacsPlateRoleResRef> newUacsPlateRoleResRefList = Lists.newArrayList();
            for (Long resId : param.getResIdList()) {
                UacsPlateRes uacsPlateRes = uacsPlateResDao.getById(resId);
                UacsPlateRoleResRef newUacsPlateRoleResRef = new UacsPlateRoleResRef();
                newUacsPlateRoleResRef.setId(IdWorker.nextId());
                newUacsPlateRoleResRef.setRoleId(role.getId());
                newUacsPlateRoleResRef.setResId(uacsPlateRes.getId());
                newUacsPlateRoleResRefList.add(newUacsPlateRoleResRef);
            }
            if (CollectionUtils.isNotEmpty(newUacsPlateRoleResRefList)) {
                uacsPlateRoleResRefDao.saveBatch(newUacsPlateRoleResRefList);
            }
        }

    }

    // 获取角色绑定的资源列表
    @Override
    public List<UacsPlateResQueryVo> getRoleBuildingResList(Long roleId) throws Exception {
        List<UacsPlateRoleResRef> roleResRefList = uacsPlateRoleResRefDao.lambdaQuery().eq(UacsPlateRoleResRef::getRoleId, roleId).list();
        if (CollectionUtils.isEmpty(roleResRefList)) {
            return Lists.newArrayList();
        }
        List<UacsPlateRes> uacsPlateRes = uacsPlateResDao.listByIds(roleResRefList.stream().map(ele -> ele.getResId()).collect(Collectors.toList()));
        return BeanHelper.copyList(uacsPlateRes, UacsPlateResQueryVo.class);
    }

}
